
// ---------------------------------------------------
// | File Name   : lcd1602.c
// | Author   	 : chagn7z
// | Create Date : 2014-6-16
// ---------------------------------------------------

#include "stm32f10x.h"
#include "user_cfg.h"
#include "lcd1602.h"

void lcd_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);

	/* GPIOA 0-7 Pin for 8bit data */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4| GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	/* GPIOC 4 5 Pin for lcd control */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOC, &GPIO_InitStruct);

	GPIO_ResetBits(GPIOC, GPIO_Pin_4 | GPIO_Pin_5);

	/* GPIOB 0 1 Pin for lcd control */
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);

	GPIO_ResetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1);

	/* init setting */
	lcd_writecmd(0x38);				//Two-line display
	delay_us(30000);
	lcd_writecmd(0x80);				//set display RAM address to 0x80
	delay_us(30000);
	lcd_writecmd(0x0e);				//display cursor and blinks
	delay_us(30000);
	lcd_writecmd(0x06);				//during change data,cursor moving right and display shift to left
	delay_us(30000);
	lcd_writecmd(0x01);
	delay_us(30000);

	LCD_LIGHT = 1;

}

void lcd_writedata(u8 dat)
{
	LCD_OE = 0;
	LCD_RS = 1;
	LCD_RW = 0;

	delay_us(LCD_NS);

	LCD_D0 = dat & 0x01 ? 1 : 0;
	LCD_D1 = dat & 0x02 ? 1 : 0;
	LCD_D2 = dat & 0x04 ? 1 : 0;
	LCD_D3 = dat & 0x08 ? 1 : 0;
	LCD_D4 = dat & 0x10 ? 1 : 0;
	LCD_D5 = dat & 0x20 ? 1 : 0;
	LCD_D6 = dat & 0x40 ? 1 : 0;
	LCD_D7 = dat & 0x80 ? 1 : 0;

	delay_us(LCD_NS);
	LCD_OE = 1;

	delay_us(LCD_NS);
	LCD_OE = 0;
	delay_us(LCD_NS);
}

void lcd_writecmd(u8 cmd)
{
	LCD_OE = 0;
	LCD_RS = 0;
	LCD_RW = 0;

	delay_us(LCD_NS);

	LCD_D0 = cmd & 0x01 ? 1 : 0;
	LCD_D1 = cmd & 0x02 ? 1 : 0;
	LCD_D2 = cmd & 0x04 ? 1 : 0;
	LCD_D3 = cmd & 0x08 ? 1 : 0;
	LCD_D4 = cmd & 0x10 ? 1 : 0;
	LCD_D5 = cmd & 0x20 ? 1 : 0;
	LCD_D6 = cmd & 0x40 ? 1 : 0;
	LCD_D7 = cmd & 0x80 ? 1 : 0;

	delay_us(LCD_NS);
	LCD_OE = 1;	

	delay_us(LCD_NS);
	LCD_OE = 0;
	delay_us(LCD_NS);		
}

void lcd_putchar(u8 line, u8 pos, u8 chr)
{
	if (chr > 9)
	{
		if (line == 1)
			lcd_writecmd(0x80+pos);
		else if (line == 2)
			lcd_writecmd(0xc0+pos);

		delay_us(30000);

		lcd_writedata(chr);
	}
	else
	{
		if (line == 1)
			lcd_writecmd(0x80+pos);
		else
			lcd_writecmd(0xc0+pos);

		delay_us(30000);

		lcd_writedata(chr+48);
	}

	delay_us(30000);
}

void lcd_putstr(u8 line, u8 pos, u8 num, u8* str)
{
	u8 i;

	// if (line == 1)
	// 	lcd_writecmd(0x80+pos);
	// else
	// 	lcd_writecmd(0xc0+pos);

	// delay_us(30000);

	// for (i=0; i<num; i++)
	// {
	// 	lcd_writedata(str[i]);
	// 	delay_us(30000);
	// }

	for (i=0; i<num; i++)
		lcd_putchar(line, pos+i, str[i]);

}

void lcd_setcursor(u8 line, u8 pos, u8 status)
{
	if (line == 1)
		lcd_writecmd(0x80+pos);
	else
		lcd_writecmd(0xc0+pos);

	delay_us(30000);

	if (status)
		lcd_writecmd(0x0d);
	else
		lcd_writecmd(0x0c);

	delay_us(30000);
}

void lcd_setline(u8 status)
{
	if (status)
		lcd_writecmd(0x0e);
	else
		lcd_writecmd(0x0c);
}

void lcd_clear(void)
{
	lcd_writecmd(0x01);

	delay_us(60000);
}
